#import "FlutterBlueCardPlugin.h"
#import "include/ESTransmitAPI.h"

#import <string>

static unsigned char* hexStr2Bytes(std::string src)
{
    char *strEnd;
    int m=0;
    int len = src.length()/2;
    unsigned char* ret = new unsigned char[len];
    
    for(int i =0;i<len;i++)
    {
        m = i*2;
        std::string subs = src.substr(m,2);
        ret[i] = strtol(subs.c_str(),&strEnd,16);
    }
    return ret;
}

@implementation FlutterBlueCardPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"flutter_blue_card_plugin"
            binaryMessenger:[registrar messenger]];
  FlutterBlueCardPlugin* instance = [[FlutterBlueCardPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  }
  else if ([@"connect" isEqualToString:call.method]) {
    [self connect:call result:result];
    return;
  }
  else if ([@"disconnect" isEqualToString:call.method]) {
    [self disconnect:call result:result];
    return;
  }
  else if ([@"sendData" isEqualToString:call.method]) {
    [self sendData:call result:result];
    return;
  }
  else {
    result(FlutterMethodNotImplemented);
  }
}

- (void)connect:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSString *sn = call.arguments[@"sn"];
    if (sn.length == 0)
        return;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
        ESTransmitError error = [[ESTransmitAPI sharedAPI] connect:sn withType:2];
        NSDictionary *arguments;
        if (error == ESTransmitSuccess) {
            arguments = @{
                @"sn": sn,
                @"code":@(0),
                @"desc":@"已连接",
            };
        }
        else {
            arguments = @{
                @"sn": sn,
                @"code":@(error),
                @"desc":@"连接失败",
            };
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            result(arguments);
        });
    });
}


- (void)disconnect:(FlutterMethodCall*)call result:(FlutterResult)result {
    [[ESTransmitAPI sharedAPI] disconnect];
    NSDictionary *arguments = @{
        @"code":@(0),
        @"desc":@"已断开连接",
    };
    result(arguments);
}


- (void)sendData:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSString* hexString = call.arguments[@"data"];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
        std::string hex(hexString.UTF8String);
        unsigned char* bytes = hexStr2Bytes(hex);
        NSData* apdu = [NSData dataWithBytes:bytes length:hexString.length/2];
        free(bytes);
        NSData* recv = [[ESTransmitAPI sharedAPI] send:apdu];
        NSString *data = [self hexStringWithData:recv];
        if (data == nil) {
            data = @"";
        }
        NSDictionary *arguments = @{
            @"code":@(0),
            @"data":[NSString stringWithFormat:@"%@9000",data],
        };
        NSLog(@"%@", data);
        dispatch_async(dispatch_get_main_queue(), ^{
            result(arguments);
        });
    });
}

- (NSString *)hexStringWithData:(NSData *)data
{
    const unsigned char* dataBuffer = (const unsigned char*)[data bytes];
    if(!dataBuffer){
        return nil;
    }
    NSUInteger dataLength = [data length];
    NSMutableString* hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
    for(int i = 0; i < dataLength; i++){
        [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
    }
    NSString* result = [NSString stringWithString:hexString];
    return result;
    
}
@end
